/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.emacs; import java.io.*; import java.util.*; import org.openide.util.WeakSet; public class EmacsProxier implements EmacsListener, Protocol { private static int proxierIDCounter = 0; private Connection conn; private final int proxierID; private boolean shutdown = false; /** * @associates EmacsProxier */ private static final Set openProxiers = Collections.synchronizedSet (new WeakSet ()); public EmacsProxier (String host, int port, String auth) throws IOException { conn = Connection.addClient (host, port, auth); synchronized (EmacsProxier.class) { proxierID = proxierIDCounter++; } conn.addEmacsListener (this); call (CMD_create); openProxiers.add (this); } public synchronized void close () { if (Connection.DEBUG) System.err.println ("close() on " + this); if (conn != null && ! shutdown) { shutdown = true; call (CMD_close); conn.removeEmacsListener (this); try { conn.removeClient (); } catch (IOException ioe) { ioe.printStackTrace (); } conn = null; } openProxiers.remove (this); } protected void finalize () throws Exception { close (); } public static void closeAll () { if (Connection.DEBUG) System.err.println ("EmacsProxier.closeAll"); Iterator it; synchronized (openProxiers) { it = new HashSet (openProxiers).iterator (); } while (it.hasNext ()) ((EmacsProxier) it.next ()).close (); } public Object[] function (String type, Object[] args) throws EmacsException { if (conn == null) throw new EmacsException (this + " is disabled, cannot call functions on it"); try { return conn.function (proxierID + ":" + type, args); } catch (EmacsException ee) { close (); throw ee; } } public Object[] function (String type) throws EmacsException { return function (type, new Object[0]); } public void call (String type, Object[] args) { if (conn == null) return; try { conn.call (proxierID + ":" + type, args); } catch (EmacsException ee) { ee.printStackTrace (); close (); } } public void call (String type) { call (type, new Object[0]); } /** * @associates EmacsListener */ private final Set listeners = new HashSet (); // Set<EmacsListener> public synchronized void addEmacsListener (EmacsListener l) { listeners.add (l); } public synchronized void removeEmacsListener (EmacsListener l) { listeners.remove (l); } public void callback (EmacsEvent ev) { String type = ev.getType (); int idx = type.indexOf (':'); // XXX debug code about who it is being sent to if (idx != -1) { try { int who = Integer.parseInt (type.substring (0, idx)); if (who == proxierID) { EmacsEvent resend = new EmacsEvent (this, type.substring (idx + 1), ev.getArgs (), ev.isOutOfSequence ()); synchronized (this) { Iterator it = listeners.iterator (); while (it.hasNext ()) ((EmacsListener) it.next ()).callback (resend); } } } catch (NumberFormatException e) { e.printStackTrace (); } } } public String toString () { return "EmacsProxier[" + conn + "#" + proxierID + "]"; } }